package fl.ass.service.service.impl;

import java.util.*;

import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.logger.eum.LogExceptionEnum;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DateUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.capital.condition.CapPayeeInfoQueryCondition;
import cn.fl.capital.constant.CapPayeeInfoConstant;
import cn.fl.capital.constant.CapitalConstant;
import cn.fl.capital.dto.CapPayeeInfoDTO;
import cn.fl.capital.service.ICapPayeeInfoApiService;
import cn.fl.project.condition.PrjPrdPaySchDQueryCondition;
import cn.fl.project.constant.PrjPrdPaySchDConstant;
import cn.fl.project.constant.PrjPrdPaySchMConstant;
import cn.fl.project.constant.PrjQuatPrpsConstant;
import cn.fl.project.constant.PrjQuatPrpsFeeConstant;
import cn.fl.project.dto.PrjPrdPaySchDDTO;
import cn.fl.project.dto.PrjPrdPaySchMDTO;
import cn.fl.project.service.IPrjPrdPaySchDApiService;
import cn.fl.project.service.IPrjPrdPaySchMApiService;
import fl.ass.facade.dto.MessageDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cmm.service.core.framework.biz.BaseBizImpl;
import cmm.service.core.framework.dao.IBaseDao;
import cn.cmm.base.framework.exception.BaseException;
import fl.ass.facade.condition.AssDealRedeemQueryCondition;
import fl.ass.facade.dto.AssDealRedeemDTO;
import fl.ass.service.dao.AssDealRedeemMapper;
import fl.ass.service.po.AssDealRedeem;
import fl.ass.service.service.IAssDealRedeemService;
import fl.ass.service.transform.AssDealRedeemTransform;

/**
 * @Description: 处置赎回表 服务层接口实现
 * @Description: 类中已经实现了简单增删改查操作,可以直接使用,如果有需要重写该方法即可：
 * @Description: 1、add(TVO entity) 2、removeById(Long id) 3、modify(DTO entity) 4、selectById(Long id)	5、searchListPage(Pager page) 7、searchList(DTO dto)   
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class AssDealRedeemServiceImpl extends BaseBizImpl<AssDealRedeem, AssDealRedeemDTO, AssDealRedeemQueryCondition> implements IAssDealRedeemService {
	
	@SuppressWarnings("unused")
	private static final Logger logger = LoggerFactory.getLogger(IAssDealRedeemService.class);
	
	@Autowired
	private AssDealRedeemMapper assDealRedeemMapper;

    @Autowired
    private IPrjPrdPaySchMApiService prjPrdPaySchMApiService;

    @Autowired
    private IPrjPrdPaySchDApiService prjPrdPaySchDApiService;

    @Autowired
    private ICapPayeeInfoApiService capPayeeInfoApiService;
	
	@Override
	public List<AssDealRedeemDTO> searchList(AssDealRedeemQueryCondition condition) throws BaseException {
		if(null == condition) return new ArrayList<AssDealRedeemDTO>();
		List<AssDealRedeem> list = this.assDealRedeemMapper.selectList(condition);
		return AssDealRedeemTransform.toDTOList(list);
	}
	
	@Override
	public IBaseDao<AssDealRedeem,AssDealRedeemQueryCondition> getDao() {
		return this.assDealRedeemMapper;
	}

    @Override
    public AssDealRedeemDTO selectByRedeemId(Long id) throws BaseException {
        return AssDealRedeemTransform.toDTO(assDealRedeemMapper.selectById(id));
    }

    @Override
    public Map<String, Double> getCalcStlCstIRRAndDiscount(Long paySchId, Long stlAmt, Date stlStDt) throws BaseException {
        if (StringUtils.isEmpty(paySchId)) {
            throw new BaseException("计算irr和结清金额优惠1时无支付表ID");
        }
        if (StringUtils.isEmpty(stlAmt)) {
            throw new BaseException("计算irr和结清金额优惠1时无结清金额");
        }
        Map<String, Double> calcStlCstIRRAndDiscount = null;
        try {
            // 查询实际放款时间
            CapPayeeInfoQueryCondition condition = new CapPayeeInfoQueryCondition();
            condition.setPaySchId(paySchId);
            condition.setIsDel(BaseConstant.IS_YESNO_NO);
            condition.setPurpCd(CapPayeeInfoConstant.CODE_PURP_CD_00000008_1);
            List<CapPayeeInfoDTO> capPayeeInfoDTOS = capPayeeInfoApiService.searchCapPayeeInfoList(condition);
            if (CollectionUtils.isNotEmpty(capPayeeInfoDTOS)) {
                CapPayeeInfoDTO capPayeeInfoDTO = capPayeeInfoDTOS.get(0);
                Date actPayTm = capPayeeInfoDTO.getActPayTm();
                if (null == actPayTm) {
                    throw new BaseException("实际放款时间不能为空！");
                }
                Integer payPd = getBetweenTwoDatesMonths(actPayTm, stlStDt);
                calcStlCstIRRAndDiscount = this.prjPrdPaySchMApiService.getCalcStlCstIRRAndDiscountForAnyPaySchId(paySchId, payPd, stlAmt, stlStDt);
                return calcStlCstIRRAndDiscount;
            }
        } catch (BaseException e) {
            BaseLogUtils.newLogger("计算对客结清irr和结清优惠金额1异常").setKeys("paySchId:" + paySchId).setWarning(false).setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        } catch (Exception e) {
            BaseLogUtils.newLogger("计算对客结清irr和结清优惠金额1异常").setKeys("paySchId:" + paySchId).setWarning(false).setThrowable(e).error(LogExceptionEnum.API_CODE_0102);
            throw e;
        }
        return null;
    }

    /**
     * 计算两个时间的月份差
     * @param startDate
     * @param endDate
     * @return
     */
    private Integer getBetweenTwoDatesMonths(Date startDate, Date endDate) {
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.setTime(startDate);
        end.setTime(endDate);
        int month = end.get(Calendar.MONTH) - start.get(Calendar.MONTH);
        int years4Month = (end.get(Calendar.YEAR) - start.get(Calendar.YEAR)) * 12;
        return Math.abs(month + years4Month);
    }

    @Override
    public boolean saveStlCstIrrAndDiscountAmt(Long redeemId, Long paySchId, Double cstStlIrr, Double discountAmt, Long usrId) throws BaseException {
        try {
            // 修改支付表的结清对客irr
            PrjPrdPaySchMDTO prjPrdPaySchMDTO = new PrjPrdPaySchMDTO();
            prjPrdPaySchMDTO.setId(paySchId);
            prjPrdPaySchMDTO.setCstStlIrr(cstStlIrr);
            this.prjPrdPaySchMApiService.modifyEntity(prjPrdPaySchMDTO);
            // 修改赎回表的应收金额
            AssDealRedeemDTO assDealRedeemDTO = this.selectByRedeemId(redeemId);
            if (null != assDealRedeemDTO) {
                assDealRedeemDTO.setReceivableAmt(assDealRedeemDTO.getRedeemAmt() - discountAmt.longValue());
                this.assDealRedeemMapper.update(AssDealRedeemTransform.toPO(assDealRedeemDTO));
            }
            // 结清优惠金额1添加到赎回对象中
            PrjPrdPaySchDQueryCondition qc = new PrjPrdPaySchDQueryCondition();
            qc.setFeeClsCd(PrjQuatPrpsConstant.CODE_PRJ_QUAT_FEE_CLS_TYP_SETT);
            qc.setIsDel(BaseConstant.IS_YESNO_NO);
            qc.setFeeTypCd(PrjQuatPrpsFeeConstant.FEE_TYP_CD_207);
            qc.setPaySchId(paySchId);
            List<PrjPrdPaySchDDTO> prjPrdPaySchDDTOS = this.prjPrdPaySchDApiService.searchPrjPrdPaySchDList(qc);
            PrjPrdPaySchDDTO prjPrdPaySchDDTO = null;
            if (CollectionUtils.isNotEmpty(prjPrdPaySchDDTOS)) {
                // 之前以保存过费用项：结清优惠金额1
                prjPrdPaySchDDTO = prjPrdPaySchDDTOS.get(0);
                prjPrdPaySchDDTO.setFeeAmt(discountAmt);
                prjPrdPaySchDDTO.setArAmt(discountAmt.longValue());
                prjPrdPaySchDDTO.setMdfUsrId(usrId);
                prjPrdPaySchDDTO.setMdfTm(new Date());
                prjPrdPaySchDDTO.setCrtUsrId(usrId);
                prjPrdPaySchDDTO.setCrtTm(new Date());
                this.prjPrdPaySchDApiService.modifyPrjPrdPaySchD(prjPrdPaySchDDTO);
            } else {
                // 新增费用项：结清优惠金额1
                prjPrdPaySchDDTO = new PrjPrdPaySchDDTO();
                prjPrdPaySchDDTO.setFeeAmt(discountAmt);
                prjPrdPaySchDDTO.setArAmt(discountAmt.longValue());
                prjPrdPaySchDDTO.setIsFixedAmt(BaseConstant.IS_YESNO_YES);
                prjPrdPaySchDDTO.setFeeClsCd(PrjQuatPrpsConstant.CODE_PRJ_QUAT_FEE_CLS_TYP_SETT);
                prjPrdPaySchDDTO.setPayPd(PrjQuatPrpsConstant.CODE_PRJ_PRD_PAY_PD);
                prjPrdPaySchDDTO.setCntWayCd(PrjQuatPrpsConstant.CODE_PRJ_QUAT_CNT_WAY_OTH);
                prjPrdPaySchDDTO.setIsDel(BaseConstant.IS_YESNO_NO);
                prjPrdPaySchDDTO.setFeeTypCd(PrjQuatPrpsFeeConstant.FEE_TYP_CD_207);
                prjPrdPaySchDDTO.setCapFlow(PrjQuatPrpsConstant.CODE_PRJ_QUAT_CASH_FLOW_OUT);
                prjPrdPaySchDDTO.setIsSysDef(BaseConstant.IS_YESNO_YES);
                prjPrdPaySchDDTO.setMdfUsrId(usrId);
                prjPrdPaySchDDTO.setMdfTm(new Date());
                prjPrdPaySchDDTO.setCrtUsrId(usrId);
                prjPrdPaySchDDTO.setCrtTm(new Date());
                prjPrdPaySchDDTO.setPaySchId(paySchId);
                this.prjPrdPaySchDApiService.addPrjPrdPaySchD(prjPrdPaySchDDTO);
            }
        } catch (BaseException e) {
            BaseLogUtils.newLogger("修改对客irr和新增结清优惠金额1失败").setKeys("redeemId:" + redeemId, "paySchId:" + paySchId).setThrowable(e).setWarning(false).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        } catch (Exception e) {
            BaseLogUtils.newLogger("修改对客irr和新增结清优惠金额1失败").setKeys("redeemId:" + redeemId, "paySchId:" + paySchId).setThrowable(e).setWarning(false).error(LogExceptionEnum.API_CODE_0102);
            throw e;
        }
        return true;
    }

    @Override
    public boolean removeStlDiscountAmt1ByPaySchId(Long paySchId) throws BaseException {
        boolean result = false;
        try {
            List<PrjPrdPaySchMDTO> prjPrdPaySchMDTOS = this.prjPrdPaySchMApiService.searchTheSamePrdOtherPaySchMList(paySchId);
            if (CollectionUtils.isNotEmpty(prjPrdPaySchMDTOS)) {
                Long wsPaySchId = null;
                for (PrjPrdPaySchMDTO prjPrdPaySchMDTO : prjPrdPaySchMDTOS) {
                    if (PrjPrdPaySchMConstant.PAY_SCH_TYP_CD_WS.equals(prjPrdPaySchMDTO.getPaySchTypCd())) {
                        wsPaySchId = prjPrdPaySchMDTO.getId();
                        break;
                    }
                }
                if (StringUtils.isNotEmpty(wsPaySchId)) {
                    PrjPrdPaySchDQueryCondition qc = new PrjPrdPaySchDQueryCondition();
                    qc.setPaySchId(wsPaySchId);
                    qc.setFeeTypCd(PrjQuatPrpsFeeConstant.FEE_TYP_CD_207);
                    qc.setIsDel(BaseConstant.IS_YESNO_NO);
                    List<PrjPrdPaySchDDTO> prjPrdPaySchDDTOS = this.prjPrdPaySchDApiService.searchPrjPrdPaySchDList(qc);
                    if (CollectionUtils.isNotEmpty(prjPrdPaySchDDTOS)) {
                        List<Long> ids = new ArrayList<>(1);
                        ids.add(prjPrdPaySchDDTOS.get(0).getId());
                        result = this.prjPrdPaySchDApiService.removePrjPrdPaySchDByIds(ids, 1002979L);
                    }
                }
            }
        } catch (BaseException e) {
            BaseLogUtils.newLogger("删除结清费用金额1失败").setKeys("paySchId:" + paySchId).setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        } catch (Exception e) {
            BaseLogUtils.newLogger("删除结清费用金额1失败").setKeys("paySchId:" + paySchId).setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        }
        return result;
    }

    @Override
    public Long addWithId(AssDealRedeemDTO dto) throws BaseException {
        return assDealRedeemMapper.addWithId(AssDealRedeemTransform.toPO(dto));
    }
}

